package com.robert.vesta.service.impl.populater;

import com.robert.vesta.service.bean.Id;
import com.robert.vesta.service.impl.bean.IdMeta;
import com.robert.vesta.service.impl.timer.Timer;
/**
 * 提供锁同步的公共模板
 */
public abstract class BasePopulator implements IdPopulator, ResetPopulator {
    protected long sequence = 0;//本个时间单位内的序列号
    protected long lastTimestamp = -1;//时间字段，用来记录上一个时间

    public BasePopulator() {
        super();
    }

    /**
     * idMeta里存储着ID的每个字段的信息
     * @param timer
     * @param id
     * @param idMeta
     */
    public void populateId(Timer timer, Id id, IdMeta idMeta) {
        long timestamp = timer.genTime();//timer来获取当前时间
        timer.validateTimestamp(lastTimestamp, timestamp);//校验时间是否正确
        /**
         * 如果当前时间和上一个时间相同，则直接对序列号累加
         * 否则，序列号清零，然后获得当前的时间，并且更新上一个时间。
         */
        if (timestamp == lastTimestamp) {
            sequence++;//如果当前时间段内产生的序列号达到最大值，则跳入下一个时间段
            sequence &= idMeta.getSeqBitsMask();
            if (sequence == 0) {
                timestamp = timer.tillNextTimeUnit(lastTimestamp);
            }
        } else {
            lastTimestamp = timestamp;
            sequence = 0;
        }

        id.setSeq(sequence);
        id.setTime(timestamp);
    }

    public void reset() {
        this.sequence = 0;
        this.lastTimestamp = -1;
    }
}
